package cn.cdeden.resource.dubbo;

import cn.cdeden.common.core.utils.StreamUtils;
import cn.cdeden.common.oss.core.OssClientBucket;
import cn.cdeden.common.oss.enumd.OssBucketOneEnum;
import cn.cdeden.common.oss.enumd.OssModuleType;
import cn.cdeden.resource.api.domain.RemoteFileDto;
import cn.cdeden.resource.domain.SysOss;
import cn.cdeden.resource.service.ISysOssDownloadRecordService;
import cn.cdeden.resource.service.ISysOssRecentlyViewedService;
import cn.cdeden.resource.utils.FileUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import cn.cdeden.common.core.exception.ServiceException;
import cn.cdeden.common.core.utils.MapstructUtils;
import cn.cdeden.common.core.utils.StringUtils;
import cn.cdeden.common.oss.entity.UploadResult;
import cn.cdeden.common.oss.factory.OssFactory;
import cn.cdeden.resource.api.RemoteFileService;
import cn.cdeden.resource.api.domain.RemoteFile;
import cn.cdeden.resource.domain.vo.SysOssVo;
import cn.cdeden.resource.service.ISysOssService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * 文件请求处理
 *
 * @author Lion Li
 */
@Slf4j
@Service
@RequiredArgsConstructor
@DubboService
public class RemoteFileServiceImpl implements RemoteFileService {

    private final ISysOssService sysOssService;

    private final ISysOssRecentlyViewedService viewedService;
    private final ISysOssDownloadRecordService downloadService;

    /**
     * 文件上传请求
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public RemoteFile upload(RemoteFileDto fileDto) throws ServiceException {
        String storageId = fileDto.getStorageId();
        String url = fileDto.getUrl(); //
        if ((storageId != null && !storageId.isEmpty()) && (url != null && !url.isEmpty())) {
            throw new IllegalArgumentException("storageId 和 url 必须都为空或只有一个为空");
        }

        //处理封面
        byte[] coverFile = fileDto.getCoverFile();
        if (ObjectUtil.isNotEmpty(coverFile)) {
            if (StringUtils.isEmpty(fileDto.getCoverContentType()) || StringUtils.isEmpty(fileDto.getCoverSuffix())) {
                throw new IllegalArgumentException("coverContentType 和 coverSuffix 必须都不为空");
            }
        }



        String originalFilename = fileDto.getOriginalFilename();
        String suffix = FileUtil.extName(originalFilename); //文件拓展名
        String fileName =  FileUtil.getPrefix(originalFilename); //文件名
        byte[] file = fileDto.getFile();
        String contentType = fileDto.getContentType(); ////文件类型
        String bucketName = fileDto.getBucketName(); ////桶
        OssModuleType moduleType = fileDto.getModuleType(); ////模块
        SysOssVo ossInfo = null;
        if (StringUtils.isNotEmpty(url)){
            ossInfo = sysOssService.getByUrl(url);
            storageId = "1";
        }

        if (StringUtils.isNotEmpty(storageId)){
            if (ossInfo == null) ossInfo = sysOssService.getById(Long.valueOf(storageId));
            if (ObjectUtil.isEmpty(ossInfo)){
                throw new ServiceException("上传文件失败");
            }else storageId = ossInfo.getOssId().toString();

            if (fileDto.isDeleteOldVersion()) { //删除旧版本
                sysOssService.deleteWithValidByIds(Arrays.asList(ossInfo.getOssId()), false);
            }else {
                try {
                    OssClientBucket storage = OssFactory.instanceBucket(ossInfo.getService());
                    //处理 覆盖上传 是否覆盖 封面处理
                    UploadResult uploadResult = storage.uploadCoverImageSuffix(
                        file,
                        contentType,
                        bucketName,
                        ossInfo.getFileName(),
                        coverFile,
                        fileDto.getCoverSuffix(),
                        fileDto.getCoverContentType()
                        );
//                    UploadResult uploadResult = storage.uploadSuffix(file, suffix, contentType,bucketName,ossInfo.getFileName());
                    sysOssService.update(ossInfo.getOssId(), uploadResult, moduleType,null);//修改数据
                    RemoteFile sysFile = new RemoteFile();
                    sysFile.setOssId(ossInfo.getOssId());
                    sysFile.setName(uploadResult.getFilename());
                    sysFile.setUrl(uploadResult.getUrl());
                    sysFile.setOriginalName(fileName);
                    sysFile.setFileSuffix(suffix);
                    sysFile.setVersionId(uploadResult.getVersionId());
                    sysFile.setVersionName( uploadResult.getVersionName());
                    sysFile.setFileSize(uploadResult.getFileSize());
                    return sysFile;
                } catch (Exception e) {
                    log.error("覆盖上传文件失败", e);
                    throw new ServiceException("覆盖上传文件失败");
                }

            }
        }

        try {
            OssClientBucket storage = OssFactory.instanceBucket();
            UploadResult uploadResult = storage.uploadCoverImageSuffix(
                file,
                coverFile,
                suffix,
                contentType,
                bucketName,
                fileDto.getCoverSuffix(),
                fileDto.getCoverContentType());

//            UploadResult uploadResult = storage.uploadSuffix(file, suffix, contentType, bucketName);
            // 保存文件信息
            SysOssVo oss = sysOssService.buildResultEntity(fileName, suffix, storage.getConfigKey(), uploadResult,moduleType);
            RemoteFile sysFile = new RemoteFile();
            sysFile.setOssId(oss.getOssId());
            sysFile.setName(uploadResult.getFilename());
            sysFile.setUrl(uploadResult.getUrl());
            sysFile.setOriginalName(fileName);
            sysFile.setFileSuffix(suffix);
            sysFile.setVersionId(oss.getVersionId());
            sysFile.setVersionName(oss.getVersionName());
            sysFile.setFileSize(uploadResult.getFileSize());
            return sysFile;
        } catch (Exception e) {
            log.error("上传文件失败", e);
            throw new ServiceException("上传文件失败");
        }


    }

    @Override
    public RemoteFile uploadCoverImage(byte[] coverFile, String coverContentType, String coverSuffix, String ossId) {
        SysOssVo ossInfo = sysOssService.getById(Long.valueOf(ossId)); //查询 oss信息 是否存在
        if (ObjectUtil.isEmpty(ossInfo)) {
            throw new ServiceException("文件的不存在无法上传文件");
        }

        OssClientBucket storage = OssFactory.instanceBucket(ossInfo.getService());
        String coverName = ossInfo.getCoverName();
        if (ObjectUtil.isNotEmpty(coverName)){
            storage.delete(OssBucketOneEnum.PUBLIC_IMAGES.getCode(), ossInfo.getCoverUrl()); //删除旧的的封面信息
        }

        UploadResult uploaded = storage.uploadCoverImage(coverFile, coverSuffix, coverContentType);
        //修改文件信息 封面的信息
        sysOssService.lambdaUpdate().eq(SysOss::getOssId, ossId)
            .set(SysOss::getCoverName, uploaded.getFilename())
            .set(SysOss::getCoverUrl, uploaded.getUrl())
            .update();

        RemoteFile sysFile = new RemoteFile();
        sysFile.setOssId(ossInfo.getOssId());
        sysFile.setCoverUrl(uploaded.getUrl());
        sysFile.setCoverName(uploaded.getFilename());
//        sysFile.setName(uploadResult.getFilename());
//        sysFile.setUrl(uploadResult.getUrl());
//        sysFile.setOriginalName(fileName);
//        sysFile.setFileSuffix(suffix);
//        sysFile.setVersionId(oss.getVersionId());
//        sysFile.setVersionName(oss.getVersionName());
//        sysFile.setFileSize(uploadResult.getFileSize());
        return sysFile;
    }

    @Override
    public boolean deleteCoverImage(String ossId) {
        SysOssVo ossInfo = sysOssService.getById(Long.valueOf(ossId)); //查询 oss信息 是否存在
        if (ObjectUtil.isEmpty(ossInfo)) {
            throw new ServiceException("操作文件的不存在");
        }

        OssClientBucket storage = OssFactory.instanceBucket(ossInfo.getService());
        String coverName = ossInfo.getCoverName();
        if (ObjectUtil.isNotEmpty(coverName)){
            storage.delete(OssBucketOneEnum.PUBLIC_IMAGES.getCode(), ossInfo.getCoverUrl()); //删除旧的的封面信息
        }
        return true;
    }


    @Override
    public RemoteFile copyFile(RemoteFile fileDto, String bucketName, OssModuleType moduleType) throws ServiceException {
        Long ossId = fileDto.getOssId();
        // 查询oss信息
        SysOssVo sysOssVo = sysOssService.getByIdAndVersionId(ossId, fileDto.getVersionId());

        OssClientBucket storage = OssFactory.instanceBucket(sysOssVo.getService());

        try {
            UploadResult uploadResult = storage.copy(
                sysOssVo.getFileName(),
                sysOssVo.getFileSuffix(),
                sysOssVo.getBucketName(),
                sysOssVo.getVersionId(),
                bucketName
            );
            SysOssVo ossInfo = sysOssService.buildResultEntity(
                sysOssVo.getOriginalName(),
                sysOssVo.getFileSuffix(),
                storage.getConfigKey(),
                uploadResult,
                moduleType
            );

            RemoteFile sysFile = new RemoteFile();
            sysFile.setOssId(ossInfo.getOssId());
            sysFile.setName(uploadResult.getFilename());
            sysFile.setUrl(uploadResult.getUrl());
            sysFile.setOriginalName(ossInfo.getOriginalName());
            sysFile.setFileSuffix(ossInfo.getFileSuffix());
            sysFile.setVersionId(ossInfo.getVersionId());
            sysFile.setVersionName(ossInfo.getVersionName());
            sysFile.setFileSize(uploadResult.getFileSize());
            return sysFile;
        }catch (Exception e){
            log.error("文件复制失败", e);
            throw new ServiceException("文件复制失败");
        }
    }




    /**
     * 通过ossId查询对应的url
     *
     * @param ossIds ossId串逗号分隔
     * @return url串逗号分隔
     */
    @Override
    public String selectUrlByIds(String ossIds) {
        return sysOssService.selectUrlByIds(ossIds);
    }

    @Override
    public String selectImageUrlByIds(String ossIds) {
        return sysOssService.selectImageUrlByIds(ossIds);
    }

    /**
     * 通过storageId查询文件消息
     *
     * @param storageId storageId串逗号分隔
     * @return 列表
     */
    @Override
    public RemoteFile selectById(String storageId) {
        SysOssVo sysOssVos = sysOssService.getById(Long.valueOf(storageId));
        return MapstructUtils.convert(sysOssVos, RemoteFile.class);
    }

    /**
     * 通过ossId查询列表
     *
     * @param ossIds ossId串逗号分隔
     * @return 列表
     */
    @Override
    public List<RemoteFile> selectByIds(String ossIds){
        List<SysOssVo> sysOssVos = sysOssService.listByIdList(StringUtils.splitTo(ossIds, Convert::toLong));
        return MapstructUtils.convert(sysOssVos, RemoteFile.class);
    }

    /**
     * 删除 文件
     * @author Yu.
     * @Date 2024/12/6 16:17
     * @param ids
     * @param isValid
     * @return java.lang.Boolean
     **/
    @Override
    @Transactional
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        try {
            List<String> list = StreamUtils.toList(ids, String::valueOf);
//            Collection<String> ids1 = ids.stream().map(String::valueOf).collect(Collectors.toList());
            Boolean viewed = viewedService.deleteViewedByModuleId(list, null, false, null);
            Boolean download = downloadService.deleteDownloadByModuleId(list, null, false, null);
        } catch (Exception e) {
            log.error("删除文件记录数据失败", e);
        }

        return sysOssService.deleteWithValidByIds(ids, isValid);
    }
}
